package com.lanyou.esb.web.serviceChannelManagement;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.JsonObject;
import com.lanyou.cook.common.Constants;
import com.lanyou.cook.entity.domain.userManagement.User;
import com.lanyou.cook.repository.userManagement.UserRepository;
import com.lanyou.cook.service.SendEmailService;
import com.lanyou.cook.service.security.UserSessionService;
import com.lanyou.cook.util.gson.GsonUtil;
import com.lanyou.esb.common.CommonUtils;
import com.lanyou.esb.datadictionary.TokenStatus;
import com.lanyou.esb.entity.Http;
import com.lanyou.esb.exception.ServiceAccessApplicationException;
import com.lanyou.esb.repository.HttpRepository;
import com.lanyou.esb.repository.ServiceChannelManagerRepository;
import com.lanyou.esb.repository.TokenRepository;
import com.lanyou.esb.service.ServiceAccessApplicationService;
import com.lanyou.esb.service.TokenService;
import com.lanyou.esb.servicemix.util.FtpRouteHandleUtil;
import com.lanyou.esb.web.param.ChannelSystemParam;
import com.lanyou.esb.web.param.InterfaceTokenEmailParam;
import com.lanyou.esb.web.param.ServiceAccessApplicationParam;
import com.lanyou.esb.web.serviceChannelManagement.vo.ServiceChannelVo;

/**
 * 服务接入申请
 * 
 * @author Davey.wu
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/serviceAccessApplication")
public class ServiceAccessApplicationController {
	@Autowired
	ServiceAccessApplicationService serviceAccessApplicationService;

	@Autowired
	private ServiceChannelManagerRepository serviceChannelManagerRepository;

	@Autowired
	private UserSessionService userSessionService;
	@Autowired
	TokenRepository interfaceTokenRepository;

	@Autowired
	private TokenService interfaceTokenService;
	
	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private HttpRepository httpRepository;
	
	@Autowired
	private SendEmailService sendEmailService;

	private static FastDateFormat FASTDATEFORMAT_YYYYMMDDHHMMSS = FastDateFormat
			.getInstance(Constants.DATETIME_PATTERN_1);

	/**
	 * 获取接口接入信息
	 * 
	 * @return 类型:String 当前登录用户可管理的领域系统的接口数据
	 */
	@RequestMapping(value = "/getHttpInterfaceInfos")
	public Page<ServiceChannelVo> getHttpInterfaceInfos(
			ChannelSystemParam param, Pageable pageable) {
		User user = userSessionService.getCurrentAuthenticatedUser();
		// 查看总记录数
		List<Object> totals = serviceChannelManagerRepository
				.findServiceChannelTotalNum(user.getId());
		BigInteger total = null;
		if (totals != null && totals.size() > 0) {
			total = (BigInteger) totals.get(0);
		}
		if (total == null || total.longValue() <= 0) {
			return new PageImpl<ServiceChannelVo>(
					new ArrayList<ServiceChannelVo>(0), new PageRequest(0, 1),
					0);
		}
		List<Object[]> list = serviceChannelManagerRepository
				.findServiceChannelInfo(user.getId(), pageable.getPageNumber()
						* pageable.getPageSize(), pageable.getPageSize());

		List<ServiceChannelVo> result = new ArrayList<ServiceChannelVo>(
				list.size());
		// 当前时间
		Date now = new Date();
		// 转换结果集
		for (Object[] objects : list) {

			ServiceChannelVo vo = new ServiceChannelVo();
			vo.setId(objects[0] != null ? (String) objects[0] : "");
			vo.setCallFieldName(objects[1] != null ? (String) objects[1] : "");
			vo.setCallSystemId(objects[2] != null ? (String) objects[2] : "");
			vo.setCallSystemName(objects[3] != null ? (String) objects[3] : "");
			vo.setPubFieldName(objects[4] != null ? (String) objects[4] : "");
			vo.setPubSystemId(objects[5] != null ? (String) objects[5] : "");
			vo.setPubSystemName(objects[6] != null ? (String) objects[6] : "");
			vo.setIfId(objects[7] != null ? (String) objects[7] : "");
			vo.setIfName(objects[8] != null ? (String) objects[8] : "");
			vo.setAppKey(objects[9] != null ? (String) objects[9] : "");
			vo.setWhiteList(objects[10] != null ? (String) objects[10] : "");
			if (objects[11] != null) {
				// yyyy-MM-dd
				vo.setAppDate(FASTDATEFORMAT_YYYYMMDDHHMMSS
						.format((Date) objects[11]));
			}
			vo.setIsEnable(objects[12] != null ? (String) objects[12] : "");
			vo.setStatus(objects[13] != null ? (String) objects[13] : "");
			// 令牌非未生效且有效期不为空，需要判断令牌是否已过有效期
			if (!TokenStatus.DISABLE.ValueCode.equals(vo.getStatus())
					&& objects[14] != null) {
				vo.setInvalidDate((Date) objects[14]);
				// 密钥是否过期
				if (vo.getInvalidDate().before(now)) {
					vo.setStatus(TokenStatus.EXPIRE.ValueCode);
				}
			}

			vo.setIds(StringUtils.isNotBlank(vo.getId()) ? Arrays.asList(vo
					.getId().split(",")) : new ArrayList<>(0));
			vo.setIfIds(StringUtils.isNotBlank(vo.getIfId()) ? Arrays.asList(vo
					.getIfId().split(",")) : new ArrayList<>(0));
			vo.setNames(StringUtils.isNotBlank(vo.getIfName()) ? Arrays
					.asList(vo.getIfName().split(",")) : new ArrayList<>(0));

			result.add(vo);
		}
		Page<ServiceChannelVo> page = new PageImpl<ServiceChannelVo>(result,
				pageable, total.longValue());
		return page;
	}

	/**
	 * 服务接入申请
	 * 
	 * @param param
	 * @return
	 */
	@RequestMapping(value = "/accessApplication", produces = "application/json", method = RequestMethod.POST)
	public String accessApplication(
			@RequestBody ServiceAccessApplicationParam param) {
		Map<String, Object> map = new HashMap<>();
		User user = userSessionService.getCurrentAuthenticatedUser();
		try {
			serviceAccessApplicationService.accessApplication(param, user);
			map.put(CommonUtils.MSG_FIELD_RESULT, 1);
		} catch (ServiceAccessApplicationException e) {
			map.put(CommonUtils.MSG_FIELD_MSG, e.getMessage());
			map.put(CommonUtils.MSG_FIELD_RESULT, 0);
		}
		return GsonUtil.getDefaultGson().toJson(map);
	}

	/**
	 * 获取密钥
	 * 
	 * @param callSystem
	 * @return
	 */
	@RequestMapping(value = "/getApplyKey", produces = "application/json")
	public String getApplyKey(String callSystem) {
		Map<String, Object> map = new HashMap<>();
		try {
			String key = serviceAccessApplicationService
					.getApplyKey(callSystem);
			map.put(CommonUtils.MSG_FIELD_KEY, key);
			map.put(CommonUtils.MSG_FIELD_RESULT, 1);
		} catch (ServiceAccessApplicationException e) {
			map.put(CommonUtils.MSG_FIELD_MSG, e.getMessage());
			map.put(CommonUtils.MSG_FIELD_RESULT, 0);
		}
		return GsonUtil.getDefaultGson().toJson(map);
	}

	/**
	 * 获取可申请的接口
	 * 
	 * @param callSystemId
	 *            ：调用方系统标识
	 * @param pubSystemId
	 *            ：发布方系统标识
	 * @return
	 */
	@RequestMapping("/getAvailableInterface")
	public String getAvailableInterface(String callSystemId, String pubSystemId) {
		User user = userSessionService.getCurrentAuthenticatedUser();
		List<Object[]> list = serviceChannelManagerRepository
				.getAvailableInterface(pubSystemId, callSystemId, user.getId());
		if (list == null) {
			return GsonUtil.getDefaultGson().toJson(new ArrayList<Http>(0));
		}
		List<Http> result = new ArrayList<Http>(list.size());
		for (Object[] object : list) {
			Http http = new Http();
			http.setId((String) object[0]);
			http.setName((String) object[1]);
			http.setCode((String) object[2]);
			result.add(http);
		}
		return GsonUtil.getDefaultGson().toJson(result);
	}

	/**
	 * 分页获取可申请的接口
	 * 
	 * @param param
	 *            ：查询参数
	 * @return
	 */
	@RequestMapping(value = "/getAvailableInterface4Page", produces = "application/json", method = RequestMethod.POST)
	public String getAvailableInterface4Page(
			@RequestBody ServiceAccessApplicationParam param) {
		// 结果
		Map<String, Object> result = new HashMap<String, Object>();
		// 调用方系统标识不能为空
		// if (StringUtils.isBlank(param.getCallSystemId())) {
		// result.put(CommonUtils.MSG_FIELD_RESULT, false);
		// result.put(CommonUtils.MSG_FIELD_MSG, "调用方系统不能为空");
		// return GsonUtil.getDefaultGson().toJson(result);
		// }
		// 发布方系统标识不能为空
		if (StringUtils.isBlank(param.getPubSystemId())) {
			result.put(CommonUtils.MSG_FIELD_RESULT, false);
			result.put(CommonUtils.MSG_FIELD_MSG, "发布方系统不能为空");
			return GsonUtil.getDefaultGson().toJson(result);
		}
		try {
			// 页码小于0，默认设为0
			if (param.getPageNumber() < 0) {
				param.setPageNumber(0);
			}
			// 页大小小于1，默认设为20
			if (param.getPageSize() < 1) {
				param.setPageSize(20);
			}
			User user = userSessionService.getCurrentAuthenticatedUser();
			// 获取可用接口
			List<Http> list = serviceAccessApplicationService
					.getAvailableInterface4Page(user.getId(),
							param.getCallSystemId(), param.getPubSystemId(),
							param.getPageNumber(), param.getPageSize());
			if (list == null) {
				list = new ArrayList<>();
			}
			result.put(CommonUtils.MSG_FIELD_RESULT, true);
			result.put(CommonUtils.MSG_FIELD_VALUE, list);
		} catch (Exception e) {
			result.put(CommonUtils.MSG_FIELD_RESULT, false);
			result.put(CommonUtils.MSG_FIELD_MSG, e.getMessage());
		}
		return GsonUtil.getDefaultGson().toJson(result);
	}

	/**
	 * 删除TOKEN
	 * 
	 * @param ids
	 * @return
	 */
	@RequestMapping(value = "/deleteToken")
	public String deleteToken(String ids) {
		Map<String, Object> map = new HashMap<>();
		if (StringUtils.isBlank(ids)) {
			map.put(CommonUtils.MSG_FIELD_MSG, "接口令牌ID为空");
			map.put(CommonUtils.MSG_FIELD_RESULT, 0);
			return GsonUtil.getDefaultGson().toJson(map);
		}
		try {
			String[] strs = ids.split(",");
			interfaceTokenService.deleteToken(Arrays.asList(strs));
			map.put(CommonUtils.MSG_FIELD_RESULT, 1);
		} catch (Exception e) {
			map.put(CommonUtils.MSG_FIELD_MSG, e.getMessage());
			map.put(CommonUtils.MSG_FIELD_RESULT, 0);
		}
		return GsonUtil.getDefaultGson().toJson(map);
	}
	
	
	/**
	 * 重新发送服务接入申请邮件给接口发布方
	 * 
	 * @param ids
	 * @return
	 */
	@RequestMapping(value = "/emailToken", produces = "application/json", method = RequestMethod.POST)
	public String emailToken(@RequestBody InterfaceTokenEmailParam param) {
		User user = userSessionService.getCurrentAuthenticatedUser();
		List<Http> https = httpRepository.findAll(param.getIfIds());
		// 将接口根据不同的用户进行分组
		Map<User, String> emailMap = new HashMap<>();
		for (Http http : https) {
			User userIf = userRepository.findByUserCode(http.getCreator());
			if (emailMap.containsKey(userIf)) {
				// 包含这个用户
				String ifName = emailMap.get(userIf);
				emailMap.put(userIf, ifName += (ifName == "" ? "" : ",") + http.getName());
			} else {
				// 不包含
				emailMap.put(userIf, http.getName());
			}
		}

		// 根据不同的用户发送服务接入申请的邮件
		for (User usr : emailMap.keySet()) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("callPerson", user.getUserCode());
			map.put("callField", param.getCallFieldName());
			map.put("callSystem", param.getCallSystemName());

			map.put("pubPerson", usr.getUserCode());
			map.put("pubField", param.getPubFieldName());
			map.put("pubSystem", param.getPubSystemName());
			map.put("ifNames", emailMap.get(usr));
			String requestIpAndPort = FtpRouteHandleUtil.getLocalHost();
			SimpleDateFormat DateTimeFormat = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
			String time = DateTimeFormat.format(new Date()).replace(" ", "#");
			String requestUrl = "http://" + requestIpAndPort + "/pages/UserManagement/UserLogin.html?time=" + time;
			map.put("requestUrl", requestUrl);

			// 接口发布方邮件地址
			map.put("emailAddress", usr.getEmailAddress());
			try {
				sendEmailService.CookSendEmail(map, Constants.SERVICE_ACESS_APPLICATION_SUBJECT,
						Constants.SERVICE_ACESS_APPLICATION_TEMPLATE);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		JsonObject jsonObject = new JsonObject();
		jsonObject.addProperty("backValue", true);
		return jsonObject.toString();
	}
}
